﻿#include "findandparsersgfx.h"

findSgfx::findSgfx()
{

}

void parseSdyFile(QString sdyPath, SdyContent &sdys) {
    QFile file(sdyPath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open file:" << sdyPath;
        return;
    }

    QXmlStreamReader reader(&file);
    MappingItem currentItem;
    QString currentParent; // 记录当前所在的父节点（"output" 或 "inputs"）
    bool inOutput = false;
    bool inInputs = false;

    while (!reader.atEnd() && !reader.hasError()) {
        QXmlStreamReader::TokenType token = reader.readNext();

        if (token == QXmlStreamReader::StartElement) {
            QString elementName = reader.name().toString();

            if (elementName == "output") {
                inOutput = true;
            } else if (elementName == "inputs") {
                inInputs = true;
            } else if (elementName == "Variable") {
                // 解析Variable属性
                if(inOutput){
                    currentParent = "output";
                } else{
                    currentParent = "inputs";
                }
                QXmlStreamAttributes attributes = reader.attributes();
                // output下的Variable属于outputItems
                currentItem.conVar.name = attributes.value("name").toString();
                currentItem.conVar.type = attributes.value("type").toString();
                currentItem.conVar.oid = attributes.value("oid").toString();
                currentItem.conVar.instancepath = attributes.value("instancepath").toString();
                QString originalString = attributes.value("subelement").toString();
                QString resultString;
                resultString.reserve(originalString.length()); // 预分配内存

                bool insideBrackets = false;
                QString currentNumber;

                int startIndex = 0;
                if (!originalString.isEmpty() && originalString[0] == '.') {
                    startIndex = 1; // 如果首字符是 '.'，则从索引 1 开始处理
                }

                for (int i = startIndex; i < originalString.length(); ++i) {
                    QChar ch = originalString[i];

                    if (ch == '[') {
                        insideBrackets = true;
                        currentNumber.clear(); // 进入新方括号，清空数字缓存
                        resultString += ch;    // 将 '[' 添加到结果中
                    } else if (ch == ']') {
                        insideBrackets = false;
                        if (!currentNumber.isEmpty()) {
                            // 处理收集到的数字：转换为整数，减一，再转换回字符串
                            bool ok;
                            int num = currentNumber.toInt(&ok);
                            if (ok) {
                                num--; // 数字减一
                                resultString += QString::number(num);
                            } else {
                                // 转换失败，保留原数字字符串
                                resultString += currentNumber;
                            }
                            currentNumber.clear();
                        }
                        resultString += ch; // 将 ']' 添加到结果中
                    } else if (insideBrackets) {
                        if (ch.isDigit()) {
                            currentNumber += ch; // 收集数字字符
                        } else {
                            resultString += currentNumber;
                            resultString += ch;
                            currentNumber.clear();
                            // insideBrackets 状态保持不变，因为仍在方括号内，但遇到了非数字字符。
                        }
                    } else {
                        resultString += ch; // 方括号外的字符直接添加
                    }
                }

                // 处理字符串末尾可能仍在方括号内且数字未处理的情况（理论上不应发生如果字符串格式正确）
                if (insideBrackets && !currentNumber.isEmpty()) {
                    bool ok;
                    int num = currentNumber.toInt(&ok);
                    if (ok) {
                        num--;
                        resultString += QString::number(num);
                    } else {
                        resultString += currentNumber;
                    }
                }

                currentItem.conVar.subelement = resultString;
                if(inInputs){
                    sdys.inputItems.append(currentItem);
                }

            } else if(elementName == "A661Data" || elementName == "DataField" || elementName == "Notify" || elementName == "Emit"){
            } else {
                // 处理其他非Variable节点
                QXmlStreamAttributes attributes = reader.attributes();
                // output下的非Variable节点记录到eventVar
                currentItem.eventVar.name = attributes.value("name").toString();
                currentItem.eventVar.layerId = attributes.value("LayerIdent").toString();
                currentItem.eventVar.widgetId = attributes.value("WidgetIdent").toString();
                if(currentItem.eventVar.widgetId == ""){
                    currentItem.eventVar.widgetId = "-1";
                }
                currentItem.eventVar.paramId = attributes.value("ParameterIdent").toString();
                if(inInputs){
                    sdys.outputItems.append(currentItem);
                }
            }
        } else if (token == QXmlStreamReader::EndElement) {
            QString elementName = reader.name().toString();

            if (elementName == "output") {
                inOutput = false;
            } else if (elementName == "inputs") {
                inInputs = false;
            } else if (elementName == "MappingItem") {
                // 重置currentItem以备下一个使用
                currentItem = MappingItem();
            }
        }
    }

    if (reader.hasError()) {
        qWarning() << "XML parse error:" << reader.errorString() << "in file:" << sdyPath;
    }

    file.close();
}

void findSgfx::parseSdyFiles(QStringList sdyPaths, SdyContent &sdys){
    for (int i = 0; i<sdyPaths.count(); i++)
    {
        parseSdyFile(sdyPaths.at(i), sdys);

    }
}

void findSgfx::parseEtpFile(QString etpPath, EtpXmlData &etpXmlData){
    //打开etp文件
    //新建QDomDocument类对象 代表一个XML文档
    QDomDocument doc;

    //创建etp文件
    QFile etpFile(etpPath);

    if (!QFile::exists(etpPath)) {
        qDebug() << "文件不存在：" << etpPath;
//        return 1;
    }


    //以只读方式打开该文件
    if (!etpFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "无法打开.sgfx文件：" << etpPath;
        etpFile.close();
//        return 1;
    }

    //将文件内容读到doc中
    if (!doc.setContent(&etpFile))
    {
        qDebug() << "设置内容失败";
        etpFile.close();
//        return 1;
    }


    // 关闭文件
    etpFile.close();

    //解析etp文件 拿到SCADE版本数据和sgfx路径
    //project
    QDomElement firstELement = doc.documentElement();
    if(firstELement.tagName() == "Project")
    {
        etpXmlData.id = firstELement.attribute("id");
        etpXmlData.oidCount = firstELement.attribute("oid_count");
        //etpXmlData.defaultConfig = firstELement.attribute("defaultConfiguration");
        QDomNodeList secondList = firstELement.childNodes();
        for(int i = 0; i < secondList.count(); i++)
        {
            QDomNode secondNode = secondList.at(i);
            QDomElement secondElement = secondNode.toElement();

            //props
            if(secondElement.tagName() == "props")
            {
                QDomNodeList thirdList = secondElement.childNodes();
                for(int j=0; j < thirdList.count(); j++)
                {
                    QDomNode thirdNode = thirdList.at(j);
                    QDomElement thirdElement = thirdNode.toElement();
                    //@SDY:RELEASE
                    if(thirdElement.attribute("name") == "@SDY:RELEASE")
                    {
                        etpXmlData.etpVersion = thirdNode.firstChild().toElement().text();
                    }
                }
            }
            //roots
            else if(secondElement.tagName() == "roots")
            {
                QDomNodeList folderList = secondElement.childNodes();
                for(int j = 0; j < folderList.count(); j++)
                {
                    QDomNode folderNode = folderList.at(j);
                    QDomElement folderElement = folderNode.toElement();

                    if(folderElement.tagName() == "Folder")
                    {
                        Folder folder;
                        folder.id = folderElement.attribute("id");
                        folder.extensions = folderElement.attribute("extensions");
                        folder.name = folderElement.attribute("name");

                        // 处理elements
                        QDomNodeList elementsList = folderElement.elementsByTagName("elements");
                        if(elementsList.count() > 0)
                        {
                            QDomNode elementsNode = elementsList.at(0);
                            QDomElement elementsElement = elementsNode.toElement();

                            QDomNodeList fileRefList = elementsElement.childNodes();
                            for(int k = 0; k < fileRefList.count(); k++)
                            {
                                QDomNode fileRefNode = fileRefList.at(k);
                                QDomElement fileRefElement = fileRefNode.toElement();

                                if(fileRefElement.tagName() == "FileRef")
                                {
                                    FileRef fileRef;
                                    fileRef.id = fileRefElement.attribute("id");
                                    fileRef.persist = fileRefElement.attribute("persistAs");

                                    // 处理FileRef的props
                                    QDomNodeList propsList = fileRefElement.elementsByTagName("props");
                                    if(propsList.count() > 0)
                                    {
                                        QDomNode propsNode = propsList.at(0);
                                        QDomElement propsElement = propsNode.toElement();

                                        QDomNodeList propList = propsElement.childNodes();
                                        for(int m = 0; m < propList.count(); m++)
                                        {
                                            QDomNode propNode = propList.at(m);
                                            QDomElement propElement = propNode.toElement();

                                            if(propElement.tagName() == "Prop")
                                            {
                                                fileProp prop;
                                                prop.id = propElement.attribute("id");
                                                prop.name = propElement.attribute("name");

                                                QDomNodeList valueList = propElement.elementsByTagName("value");
                                                if(valueList.count() > 0)
                                                {
                                                    prop.value = valueList.at(0).toElement().text();
                                                }

                                                fileRef.fileProps.propList.append(prop);
                                            }
                                        }
                                    }

                                    folder.elements.fileRefList.append(fileRef);

                                    // 特殊处理Model Files中的sgfx路径
                                    if(folderElement.attribute("name") == "Model Files" &&
                                        fileRefElement.attribute("persistAs").endsWith(".sgfx"))
                                    {
                                        etpXmlData.sgfxPath.append(fileRefElement.attribute("persistAs"));
                                    }
                                }
                            }
                        }

                        etpXmlData.etpRoots.folderList.append(folder);
                    }
                }
            }
            //configurations
            else if(secondElement.tagName() == "configurations")
            {
                QDomNodeList configList = secondElement.childNodes();
                for(int j = 0; j < configList.count(); j++)
                {
                    QDomNode configNode = configList.at(j);
                    QDomElement configElement = configNode.toElement();

                    if(configElement.tagName() == "Configuration")
                    {
                        Configuration config;
                        config.id = configElement.attribute("id");
                        config.name = configElement.attribute("name");

                        etpXmlData.configs.configList.append(config);
                    }
                }
            }
        }
    }
}


/*========================widget解析==========================*/

// 递归解析XML结构的函数
void findSgfx::parseXmlNode(const QDomNode& node, WidgetChildren& widgetChildren, const QMap<QString, QString> &constMap) {
    // 解析 XML 节点，将其转换为 WidgetChildren 结构


    // 获取当前节点的所有子节点
    QDomNodeList nodeList = node.childNodes();
    // 创建 WidgetContainer 实例，用于存储当前节点的信息
    WidgetContainer widgetContainer;

    // 遍历当前节点的所有子节点
    for (int i = 0; i < nodeList.count(); ++i) {
        // 获取当前子节点
        QDomNode childNode = nodeList.at(i);
        // 将子节点转换为元素
        QDomElement childElement = childNode.toElement();

        // 检查子节点是否有效
        if (!childElement.isNull()) {

            // 从子元素中提取对象标识符属性
            widgetContainer.dllProperties.name = childElement.attribute("name");
            widgetContainer.oid = childElement.attribute("oid");
            widgetContainer.dllProperties.type = childElement.attribute("type");
            widgetContainer.dllProperties.posX = "0";
            widgetContainer.dllProperties.posY = "0";

            // 创建新的 WidgetChildren 实例，用于存储子节点信息
            WidgetChildren childWidgetChildren;
            // 获取子节点的所有属性节点
            QDomNodeList widgetAttList = childNode.childNodes();
            // 遍历子节点的属性节点
            for(int j = 0; j < widgetAttList.count(); j++)
            {
                // 获取属性节点
                QDomNode widgetAttNode = widgetAttList.at(j);
                // 将属性节点转换为元素
                QDomElement widgetAttElement = widgetAttNode.toElement();

                //IDE
                if(widgetAttElement.tagName() == "IDE")
                {

                }
                //model
                else if(widgetAttElement.tagName() == "model")
                {
                    widgetContainer.dllProperties.inputParameters.paramers.clear();
                    widgetContainer.dllProperties.extensions.extensionList.clear();
                    //变量值读取操作
                    QDomNodeList parameterList = widgetAttNode.childNodes();

                    for(int m = 0; m < parameterList.count(); m++)
                    {
                        Parameter parameter;

                        QDomNode parameterNode = parameterList.at(m);
                        QDomElement parameterElement = parameterNode.toElement();

                        if(parameterElement.attribute("name") == "PosX" || parameterElement.attribute("name") == "PosXStart"){
                            widgetContainer.dllProperties.posX = parameterElement.text();
                        }
                        else if(parameterElement.attribute("name") == "PosY" || parameterElement.attribute("name") == "PosYStart"){
                            widgetContainer.dllProperties.posY = parameterElement.text();
                        }

                        if(parameterElement.attribute("name") == "EntryList")
                        {
                            parameter.name = parameterElement.attribute("name");

                            QString entryStr;

                            QDomNodeList entryList = parameterNode.childNodes();
                            for(int n = 0; n < entryList.count(); n++)
                            {
                                QDomNode entryNode = entryList.at(n);
                                QDomElement entryElement = entryNode.toElement();
                                QString t = entryElement.tagName();
                                QString e = entryElement.text();
                                QString name = entryElement.attribute("name");

                                entryStr = entryStr + entryElement.text() +";";
                            }
                            entryStr.chop(1);
                            parameter.initValue = entryStr;
                            parameter.type = "initprop";
                        }
                        else if(parameterElement.attribute("name") == "Vertices")
                        {
                            parameter.name = parameterElement.attribute("name");

                            QString entryStr;

                            QDomNodeList entryList = parameterNode.childNodes();
                            for(int n = 0; n < entryList.count(); n++)
                            {
                                QDomNode entryNode = entryList.at(n);
                                QDomNodeList xyList = entryNode.childNodes();
                                QDomNode xNode = xyList.at(0);
                                QDomNode yNode = xyList.at(1);
                                QDomElement entryElement = entryNode.toElement();
                                QString t = entryElement.tagName();
                                QString e = entryElement.text();
                                QString name = entryElement.attribute("name");
                                QDomElement xElement = xNode.toElement();
                                QDomElement yElement = yNode.toElement();
                                QString xText = xElement.text();
                                QString yText = yElement.text();

                                entryStr = entryStr + "(" +  xText + "," + yText + ")" +";";
                            }
                            entryStr.chop(1);
                            parameter.initValue = entryStr;
                            parameter.type = "initprop";
                        }
                        else if(parameterElement.tagName() == "arrayprop"){
                            parameter.name = parameterElement.attribute("name");

                            QString entryStr;

                            QDomNodeList entryList = parameterNode.childNodes();
                            for(int n = 0; n < entryList.count(); n++)
                            {
                                QDomNode entryNode = entryList.at(n);
                                QDomElement xElement = entryNode.toElement();
                                QString xText = xElement.text();

                                entryStr = entryStr +  xText + ";";
                            }
                            entryStr.chop(1);
                            parameter.initValue = entryStr;
                            parameter.type = "initprop";
                        }
                        else
                        {
                            parameter.name = parameterElement.attribute("name");
                            parameter.initValue = parameterNode.toElement().text();
                            if(parameter.name == "Visible"){
                                if(parameter.initValue == "A661_TRUE"){
                                    widgetContainer.dllProperties.visible.value = "true";
                                }
                                else if(parameter.initValue == "A661_FALSE"){
                                    widgetContainer.dllProperties.visible.value = "false";
                                }
                            }

                            if(parameter.name == "StyleSet" || parameter.name == "PictureReference"){
                                parameter.type = "initprop";
                            }
                            else if(parameterNode.toElement().tagName() == "enumprop"){
                                parameter.enumValue = parameterNode.toElement().text();
                                parameter.type = "enumprop";
                            }
                            else{
                                parameter.type = parameterNode.toElement().tagName();
                            }
                            

                        }

                        widgetContainer.dllProperties.inputParameters.paramers.append(parameter);
                    }
                }
                //extensions
                else if (widgetAttElement.tagName() == "extensions")
                {
                    QDomNodeList extensionList = widgetAttNode.childNodes();
                    Extensions extensions;

                    for(int m = 0; m < extensionList.count(); m++){

                        Extension extension;

                        QDomNode extensionNode = extensionList.at(m);
                        QDomElement extensionElement = extensionNode.toElement();

                        extension.name = extensionElement.attribute("type");

                        QDomNodeList propList = extensionNode.childNodes();
                        for(int n = 0; n < propList.count(); n++){
                            QDomNode propNode = propList.at(n);
                            QDomElement propElement = propNode.toElement();

                            Parameter param;

                            param.name = propElement.attribute("name");

                            param.type = propElement.tagName();

                            param.initValue = propNode.toElement().text();

                            if(param.type == "enumprop")
                            {
                                param.enumValue = propNode.toElement().text();
                                param.initValue = constMap[param.enumValue];
                                param.enumType = "";
                            }
                            else if(param.type == "arrayprop"){
                                param.initValue = "";
                                param.enumValue = "";
                                QDomNodeList arrayList = propNode.childNodes();
                                for(int t = 0; t < arrayList.count(); t++){
                                    QDomNode arrayNode = arrayList.at(t);
                                    QDomElement arrayElement = arrayNode.toElement();
                                    if(arrayElement.tagName() == "enumprop"){
                                        param.enumValue += arrayElement.text() + ";";
                                        QString iValue = constMap[arrayElement.text()];
                                        param.initValue += iValue + ";";
                                        param.type = "enumprop";
                                        param.enumType = "";
                                    }
                                    else{
                                        param.initValue += arrayElement.text() + ";";
                                    }
                                }
                                param.initValue.chop(1);
                                if(param.enumValue != ""){
                                    param.enumValue.chop(1);
                                }
                            }

                            extension.eParams.append(param);

                        }
                        extensions.extensionList.append(extension);
                    }
                    widgetContainer.dllProperties.extensions = extensions;


                }
                // 如果当前属性节点是子节点，则递归处理
                else if (widgetAttElement.tagName() == "children") {

                    // 递归调用 parseXmlNode 处理子节点
                    parseXmlNode(widgetAttNode, childWidgetChildren, constMap);

                }

            }
            // 将处理好的子节点添加到当前节点的 DLL 属性中
            widgetContainer.dllProperties.addchildren(&childWidgetChildren);

            // 将当前节点的信息添加到 WidgetChildren 结构中
            widgetChildren.widgets.append(widgetContainer);
        }
    }

}




void findSgfx::parseSgfxFile(QString sgfxPath, SGFX &sgfx, const QMap<QString, QString> &constMap)
{
    /*=====================文件打开内容设置=======================*/
    //新建QDomDocument类对象 代表一个XML文档
    QDomDocument doc;

    //创建sgfx文件
    QFile sgfxFile(sgfxPath);

    if (!QFile::exists(sgfxPath)) {
        qDebug() << "文件不存在：" << sgfxPath;
    }


    //以只读方式打开该文件
    if (!sgfxFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "无法打开.sgfx文件：" << sgfxPath;
        sgfxFile.close();
    }

    //将文件内容读到doc中
    if (!doc.setContent(&sgfxFile))
    {
        qDebug() << "设置内容失败";
        sgfxFile.close();
    }


    // 关闭文件
    sgfxFile.close();

    /*====一层 specification====*/
    // specification
    QDomElement firstELement = doc.documentElement();
    if(firstELement.toElement().tagName()=="specification")
    {
//        QString specOid = firstELement.attribute("oid");
//        sgfx.specification.oid = specOid;
        QUuid uuid = QUuid::createUuid(); // 生成 UUID
        sgfx.specification.oid = "{"+uuid.toString(QUuid::WithoutBraces)+"}";

        /*======二层 ide symbology A661 redace_control children========*/
        QDomNodeList secondList = firstELement.childNodes();

        for(int i = 0; i < secondList.count(); i++)
        {
            QDomNode secondNode = secondList.at(i);
            QDomElement secondElement = secondNode.toElement();

            /*=======三层=======*/
            QDomNodeList thirdList = secondElement.childNodes();

            //ide
            if(secondElement.tagName()=="IDE")
            {
                for(int j = 0; j < thirdList.count(); j++)
                {
                    QDomNode thirdNode = thirdList.at(j);
                    QDomElement thirdElement = thirdNode.toElement();

                    //project
                    if(thirdElement.tagName()=="project")
                    {
                        QFileInfo absSgfxPath(sgfxPath);
                        sgfx.specification.ide.project.path = sgfx.etpPath;
                    }
                    //ratio
                    else if(thirdElement.tagName()=="ratio")
                    {
                        sgfx.specification.ide.ratio.Horizontal = thirdElement.attribute("horizontal");
                        sgfx.specification.ide.ratio.Vertical = thirdElement.attribute("vertical");
                    }
                }
            }
            //symbology
            else if(secondElement.tagName()=="symbology")
            {
                for(int j = 0; j < thirdList.count(); j++)
                {
                    QDomNode thirdNode = thirdList.at(j);
                    QDomElement thirdElement = thirdNode.toElement();

                    //colorMode
                    if(thirdElement.tagName()=="colorMode")
                    {
                        sgfx.specification.Symbology.colorMode.value = thirdElement.attribute("value");
                    }
                    //dimension
                    else if(thirdElement.tagName()=="dimension")
                    {
                        sgfx.specification.Symbology.colorMode.value = "RGBA";
                        sgfx.specification.Symbology.demension.height = thirdElement.attribute("height");
                        sgfx.specification.Symbology.demension.width = thirdElement.attribute("width");
                    }
                }
            }
            //a661
            else if(secondElement.tagName()=="A661")
            {
                sgfx.specification.a661.libraryVersion.value = secondElement.attribute("library_version");
                sgfx.specification.a661.suppVersion.value = secondElement.attribute("supp_version");

                for(int j = 0; j < thirdList.count(); j++)
                {
                    QDomNode thirdNode = thirdList.at(j);
                    QDomElement thirdElement = thirdNode.toElement();

                    //intprop
                    if(thirdElement.tagName()=="intprop")
                    {
                        sgfx.specification.a661.applicationId.value = thirdElement.text();
                    }
                }
            }

            //children
            else if(secondElement.tagName()=="children")
            {
                if(thirdList.count() != 0)
                {
                    //layers
                    for(int j = 0; j < thirdList.count(); j++)
                    {
                        Layer layer;
                        QDomNode thirdNode = thirdList.at(j);
                        QDomElement thirdElement = thirdNode.toElement();

                        //A661Layer
                        if(thirdElement.tagName() == "A661Layer")
                        {
                            layer.oid = thirdElement.attribute("oid");
                            layer.layerProperties.name = thirdElement.attribute("name");

                            /*===========第四层===============*/
                            QDomNodeList fourList = thirdNode.childNodes();

                            for(int k = 0; k <fourList.count(); k++)
                            {
                                QDomNode fourNode = fourList.at(k);
                                QDomElement fourElement = fourNode.toElement();

                                //IDE
                                if(fourElement.tagName() == "IDE")
                                {
                                    /*=====================第五层===========================*/
                                    QDomNodeList fifList = fourNode.childNodes();

                                    for(int m = 0; m < fifList.count(); m++)
                                    {
                                        QDomNode fifNode = fifList.at(m);
                                        QDomElement fifElement = fifNode.toElement();

                                        //ratio
                                        if(fifElement.tagName() == "ratio")
                                        {
                                            layer.layerProperties.ratio.Horizontal =
                                                    fifElement.attribute("horizontal");
                                            layer.layerProperties.ratio.Vertical =
                                                    fifElement.attribute("vertical");
                                        }
                                    }

                                }
                                //model
                                else if (fourElement.tagName() == "model")
                                {

                                    /*=====================第五层===========================*/
                                    QDomNodeList fifList = fourNode.childNodes();

                                    for(int n = 0; n < fifList.count(); n++)
                                    {
                                        QDomNode fifNode = fifList.at(n);
                                        QDomElement fifElement = fifNode.toElement();

                                        //LayerId
                                        if((fifElement.tagName() == "intprop")&&(fifElement.attribute("name") == "LayerId"))
                                        {
                                            layer.pathFormRoot.value = fifElement.text();
                                            layer.layerId = fifElement.text();
                                        }
                                        //ContextNumber
                                        else if ((fifElement.tagName() == "intprop")&&(fifElement.attribute("name") == "ContextNumber"))
                                        {
                                            layer.contextNumber = fifElement.text();
                                        }
                                        //Width
                                        else if ((fifElement.tagName() == "intprop")&&(fifElement.attribute("name") == "Width"))
                                        {
                                            layer.width = QString::number(fifElement.text().toInt() / 20);
                                        }
                                        //Height
                                        else if ((fifElement.tagName() == "intprop")&&(fifElement.attribute("name") == "Height"))
                                        {
                                            layer.height = QString::number(fifElement.text().toInt() / 20);
                                        }
                                    }
                                }
                                else if (fourElement.tagName() == "runtime"){

                                }
                                else if (fourElement.tagName() == "events"){

                                }
                                else if (fourElement.tagName() == "children")
                                {
                                    WidgetChildren widgetChildren;
                                    parseXmlNode(fourNode, widgetChildren, constMap);

                                    layer.widgetChildren = widgetChildren;
                                }
                            }
                        }
                        sgfx.specification.layerChildren.layers.append(layer);
                    }
                }
                else
                {

                }
            }
        }
    }
}

bool parsePropTypesXml(const QString& filePath, PropTypes& outProps) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open file:" << filePath;
        return false;
    }

    QXmlStreamReader reader(&file);
    PropTypes tempProps;
    bool parseSuccess = true;

    while (!reader.atEnd() && !reader.hasError()) {
        QXmlStreamReader::TokenType token = reader.readNext();

        if (token == QXmlStreamReader::StartElement) {
            const QString elementName = reader.name().toString();
            QList<QString>* targetList = nullptr;

            // 确定要填充的列表
            if (elementName == "posYList") {
                targetList = &tempProps.posYList;
            }
            else if (elementName == "posXList") {
                targetList = &tempProps.posXList;
            }
            else if (elementName == "m20List") {
                targetList = &tempProps.m20List;
            }
            else if (elementName == "angleList") {
                targetList = &tempProps.angleList;
            }
            else if (elementName == "arrayList") {
                targetList = &tempProps.arrayList;
            }
            else if (elementName == "intList") {
                targetList = &tempProps.intList;
            }
            else if (elementName == "enumList") {
                targetList = &tempProps.enumList;
            }
            else if (elementName == "stringList") {
                targetList = &tempProps.stringList;
            }
            else if (elementName == "e2iMap") {
                // 处理e2iMap节点
                while (!(reader.tokenType() == QXmlStreamReader::EndElement &&
                         reader.name() == "e2iMap")) {
                    reader.readNext();

                    if (reader.tokenType() == QXmlStreamReader::StartElement &&
                        reader.name() == "item") {
                        QXmlStreamAttributes attributes = reader.attributes();
                        QString enumValue = attributes.value("enum").toString();
                        QString initValue = attributes.value("init").toString();

                        if (!enumValue.isEmpty() && !initValue.isEmpty()) {
                            tempProps.enum2initMap.insert(enumValue, initValue);
                        }
                    }
                }
                continue;
            }

            // 如果找到目标列表，解析其中的item元素
            if (targetList) {
                const QString listName = elementName; // 保存当前列表名用于结束判断
                while (!(reader.tokenType() == QXmlStreamReader::EndElement &&
                         reader.name() == listName)) {
                    reader.readNext();

                    if (reader.tokenType() == QXmlStreamReader::StartElement &&
                        reader.name() == "item") {
                        targetList->append(reader.readElementText());
                    }
                }
            }
        }
    }

    if (reader.hasError()) {
        qWarning() << "XML parse error:" << reader.errorString();
        parseSuccess = false;
    }

    file.close();

    if (parseSuccess) {
        outProps = tempProps;
        qDebug() << "Successfully parsed propTypes.xml";
    }

    return parseSuccess;
}

bool parseConstXml(const QString& filePath, QMap<QString, QString> &constMap) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open file:" << filePath;
        return false;
    }

    QXmlStreamReader reader(&file);
    bool parseSuccess = true;

    while (!reader.atEnd() && !reader.hasError()) {
        QXmlStreamReader::TokenType token = reader.readNext();

        if (token == QXmlStreamReader::StartElement) {
            const QString elementName = reader.name().toString();

            if (elementName == "const") {
                QXmlStreamAttributes attributes = reader.attributes();
                QString enumValue = attributes.value("name").toString();
                QString initString = reader.readElementText();
                initString = initString.replace("0x", "");
                int initValue = initString.toInt(nullptr, 16);
                constMap.insert(enumValue, QString::number(initValue));
            }
        }
    }

    if (reader.hasError()) {
        qWarning() << "XML parse error:" << reader.errorString();
        parseSuccess = false;
    }

    file.close();

    if (parseSuccess) {
        qDebug() << "Successfully parsed const.xml";
    }

    return parseSuccess;
}

bool parseCommunicationXml(const QString& filePath, CommuParams &commuParams) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open file:" << filePath;
        return false;
    }

    QXmlStreamReader reader(&file);
    bool parseSuccess = true;
    ComWidget currentWidget;
    Event currentEvent;
    Variable currentVar;
    QString currentElementName;
    bool inCmdSetParameter = false;
    bool inNotifyWidgetEvent = false;
    bool inEventElement = false;

    while (!reader.atEnd() && !reader.hasError()) {
        QXmlStreamReader::TokenType token = reader.readNext();

        if (token == QXmlStreamReader::StartElement) {
            currentElementName = reader.name().toString();

            // Check if we're starting a new widget (non-A661 element)
            if (!currentElementName.startsWith("A661_") &&
                currentElementName != "var" &&
                currentElementName != "widgets") {

                // If we have a current widget with data, add it to commuParams
                if (!currentWidget.name.isEmpty() &&
                    (!currentWidget.msgs.isEmpty() || !currentWidget.ntfs.isEmpty())) {
                    commuParams.widgets.append(currentWidget);
                }

                // Start a new widget
                currentWidget = ComWidget();
                currentWidget.name = currentElementName;
                currentWidget.msgs.clear();
                currentWidget.ntfs.clear();
            }
            else if (currentElementName == "A661_CMD_SET_PARAMETER") {
                inCmdSetParameter = true;
                inNotifyWidgetEvent = false;
            }
            else if (currentElementName == "A661_NOTIFY_WIDGET_EVENT") {
                inNotifyWidgetEvent = true;
                inCmdSetParameter = false;
            }
            else if (currentElementName == "var") {
                // Parse variable attributes
                currentVar.name = reader.attributes().value("name").toString();
                currentVar.id = reader.attributes().value("id").toString();
                currentVar.type = reader.attributes().value("type").toString();

                // Add the variable to the current event
                if (inEventElement) {
                    currentEvent.vars.append(currentVar);
                }
            }
            else if ((inCmdSetParameter || inNotifyWidgetEvent) &&
                     currentElementName.startsWith("A661_")) {
                // This is an event element (like A661_EVT_SELECTION, etc.)
                currentEvent.name = currentElementName;
                currentEvent.vars.clear();
                inEventElement = true;
            }
        }
        else if (token == QXmlStreamReader::EndElement) {
            QString elementName = reader.name().toString();

            if (elementName == "A661_CMD_SET_PARAMETER") {
                inCmdSetParameter = false;
            }
            else if (elementName == "A661_NOTIFY_WIDGET_EVENT") {
                inNotifyWidgetEvent = false;
            }
            else if ((inCmdSetParameter || inNotifyWidgetEvent) &&
                     elementName == currentEvent.name) {
                // End of event element - add to appropriate list
                if (inCmdSetParameter) {
                    currentWidget.msgs.append(currentEvent);
                } else {
                    currentWidget.ntfs.append(currentEvent);
                }
                inEventElement = false;
            }
        }
    }

    // Add the last widget if it has data
    if (!currentWidget.name.isEmpty() &&
        (!currentWidget.msgs.isEmpty() || !currentWidget.ntfs.isEmpty())) {
        commuParams.widgets.append(currentWidget);
    }

    if (reader.hasError()) {
        qWarning() << "XML parse error:" << reader.errorString();
        parseSuccess = false;
    }

    file.close();

    return parseSuccess;
}


void findSgfx::rulesRead(Rules &rules, const QString &rulesFolderPath, PropTypes &propTypes, QMap<QString, QString> &constMap, CommuParams &commuParams){
    QDir rulesDir(rulesFolderPath);
    QStringList xmlFiles = rulesDir.entryList(QStringList() << "*.xml", QDir::Files);
    QList<QString> containers;

    for (const QString &file : xmlFiles) {
        QFile xmlFile(rulesDir.filePath(file));
        if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
            continue;

        QXmlStreamReader reader(&xmlFile);
        Rule rule;
        Widget widget;

        if (QFileInfo(file).fileName() == "propTypes.xml") {
            QString absolutePath = rulesDir.filePath(file);
            if (!parsePropTypesXml(absolutePath, propTypes)) {
                qWarning() << "Failed to parse propTypes.xml";
            }
            continue;
        }
        if (QFileInfo(file).fileName() == "communication.xml") {
            QString absolutePath = rulesDir.filePath(file);
            if (!parseCommunicationXml(absolutePath, commuParams)) {
                qWarning() << "Failed to parse communication.xml";
            }
            continue;
        }
        else if(QFileInfo(file).fileName() == "const.xml"){
            QString absolutePath = rulesDir.filePath(file);
            if (!parseConstXml(absolutePath, constMap)) {
                qWarning() << "Failed to parse const.xml";
            }
            continue;
        }
        else if(QFileInfo(file).fileName() == "a661.xml")
        {
            bool inContainersSection = false;
            while (!reader.atEnd() && !reader.hasError())
            {
                QXmlStreamReader::TokenType token = reader.readNext();

                if (token == QXmlStreamReader::Comment)
                {
                    QString comment = reader.text().toString().trimmed();
                    if (comment == "Containers")
                    {
                        inContainersSection = true;
                    }
                    else if (comment == "Graphics")
                    {
                        break; // 结束循环，已经到达Graphics部分
                    }
                }
                else if (inContainersSection && token == QXmlStreamReader::StartElement && reader.name() == "widget")
                {
                    QString widgetFile = reader.readElementText();
                    // 去掉.xml后缀并添加到widget对象中
                    if (widgetFile.endsWith(".xml"))
                    {
                        widgetFile.chop(4);
                    }
                    containers.append(widgetFile);
                }
            }

            if (reader.hasError())
            {
                qWarning() << "XML error:" << reader.errorString();
            }
        }

        while (!reader.atEnd() && !reader.hasError()) {
            QXmlStreamReader::TokenType token = reader.readNext();

            int n = 0;
            QString name = reader.name().toString();
            if(name!= "")
            {
                n+=1;
            }
            if(n == 1 && name != "widget")
            {
                break;
            }
            if (token == QXmlStreamReader::StartElement && name == "widget") {
                rule.name = reader.attributes().value("name").toString();
                if(rule.name == "WatchdogContainer"){
                    QString s;
                }
                rule.hasChildren = false;

                // 处理model分支
                while (reader.readNextStartElement()) {
                    if (reader.name() == "model") {
                        // 处理IDE分支
                        while (reader.readNextStartElement()) {
                            if (reader.name() == "IDE") {
                                widget.model.mide.value = "";
                                reader.skipCurrentElement();
                            }
                            // 处理definition分支
                            else if (reader.name() == "definition") {
                                Definition def;
                                while (reader.readNextStartElement()) {
                                    if (reader.name() == "prop") {
                                        Prop prop;
                                        prop.name = reader.attributes().value("name").toString();
                                        while (reader.readNextStartElement()) {
                                            if (reader.name() == "default") {
                                                // Get the first child element of default
                                                if (reader.readNextStartElement()) {
                                                    prop.type = reader.name().toString(); // Store the child node name
                                                    if (reader.attributes().hasAttribute("enumType")) {
                                                        prop.enumType = reader.attributes().value("enumType").toString();
                                                    }
                                                    reader.skipCurrentElement(); // Skip the child element
                                                }
                                            }
                                            reader.skipCurrentElement(); // Skip other elements
                                        }
                                        def.props.append(prop);
                                    } else if (reader.name() == "padding") {
                                        Padding pad;
                                        pad.padBytes = reader.attributes().value("padBytes").toString();
                                        pad.align = reader.attributes().value("align").toString();
                                        def.paddings.append(pad);
                                        reader.skipCurrentElement();
                                    } else {
                                        reader.skipCurrentElement();
                                    }
                                }
                                widget.model.definition = def;
                            }
                            // 处理runtime分支
                            else if (reader.name() == "runtime") {
                                ModelRunTime runtime;
                                while (reader.readNextStartElement()) {
                                    if (reader.name() == "msg") {
                                        Msg msg;
                                        msg.value = "";
                                        runtime.msgs.append(msg);
                                        reader.skipCurrentElement();
                                    } else {
                                        reader.skipCurrentElement();
                                    }
                                }
                                widget.model.modelRunTime = runtime;
                            }
                            else {
                                reader.skipCurrentElement();
                            }
                        }

                    }

                    // 处理events分支
                    else if (reader.name() == "events") {
                        WidgetEvents events;
                        while (reader.readNextStartElement()) {
                            if (reader.name() == "msg") {
                                EventMsg em;
                                em.msgType = reader.attributes().value("type").toString();
                                events.EventMsgs.append(em);
                            }
                            reader.skipCurrentElement();
                        }
                        widget.events = events;
                    }
                    else {
                        reader.skipCurrentElement();
                    }
                }
            }
        }

        if (!reader.hasError()) {
            // 后处理默认值
            if (!rule.name.isEmpty())
            {
                rule.widget = widget;
                rules.rules.append(rule);
            }
        }
        xmlFile.close();
    }

    for(Rule &rule:rules.rules){
        if(containers.contains(rule.name)){
            rule.isContainer = true;
        }
        else{
            rule.isContainer = false;
        }
    }

    QFile hierarchyFile(rulesDir.filePath("a661hierarchy.xml"));
    if (hierarchyFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QXmlStreamReader reader(&hierarchyFile);

        // 创建哈希表存储widget和其子widget的关系
        QHash<QString, QStringList> widgetHierarchy;

        while (!reader.atEnd() && !reader.hasError()) {
            QXmlStreamReader::TokenType token = reader.readNext();

            if (token == QXmlStreamReader::StartElement && reader.name() == "widget") {
                QString widgetName = reader.attributes().value("name").toString();
                QStringList children;

                // 读取所有子元素
                while (reader.readNextStartElement()) {
                    if (reader.name() == "child") {
                        children.append(reader.readElementText());
                    } else {
                        reader.skipCurrentElement();
                    }
                }

                if (!children.isEmpty()) {
                    widgetHierarchy.insert(widgetName, children);
                }
            }
        }

        if (!reader.hasError()) {
            // 更新rules中的hasChildren标志
            for (Rule &rule : rules.rules) {
                if (widgetHierarchy.contains(rule.name)) {
                    rule.hasChildren = true;
                }
            }
        }

        hierarchyFile.close();
    }
}

void findSgfx::extensionRulesRead(ExtensionRules &eRules, const QString &rulesFolderPath){
    QDir rulesDir(rulesFolderPath);
    QStringList xmlFiles = rulesDir.entryList(QStringList() << "*.xml", QDir::Files);

    for (const QString &file : xmlFiles) {
        QFile xmlFile(rulesDir.filePath(file));
        if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
            continue;

        QXmlStreamReader reader(&xmlFile);
        ExtensionRule rule;
        WidgetExtension widget;

        while (!reader.atEnd() && !reader.hasError()) {
            QXmlStreamReader::TokenType token = reader.readNext();

            int n = 0;
            QString name = reader.name().toString();
            if(name!= "")
            {
                n+=1;
            }
            if(n == 1 && name != "widgetExtension")
            {
                break;
            }
            if (token == QXmlStreamReader::StartElement && reader.name() == "widgetExtension") {
                rule.name = reader.attributes().value("name").toString();

                // 处理model分支
                while (reader.readNextStartElement()) {
                    if (reader.name() == "model") {
                        // 处理IDE分支
                        while (reader.readNextStartElement()) {
                            if (reader.name() == "IDE") {
                                widget.model.mide.value = "";
                                reader.skipCurrentElement();
                            }
                            // 处理definition分支
                            else if (reader.name() == "definition") {
                                Definition def;
                                while (reader.readNextStartElement()) {
                                    if (reader.name() == "prop") {
                                        Prop prop;
                                        prop.name = reader.attributes().value("name").toString();
                                        while (reader.readNextStartElement()) {
                                            if (reader.name() == "default") {
                                                // Get the first child element of default
                                                if (reader.readNextStartElement()) {
                                                    prop.type = reader.name().toString(); // Store the child node name
                                                    if (reader.attributes().hasAttribute("enumType")) {
                                                        prop.enumType = reader.attributes().value("enumType").toString();
                                                    }
                                                    reader.skipCurrentElement(); // Skip the child element
                                                }
                                            }
                                            reader.skipCurrentElement(); // Skip other elements
                                        }
                                        def.props.append(prop);
                                    } else if (reader.name() == "padding") {
                                        Padding pad;
                                        pad.padBytes = reader.attributes().value("padBytes").toString();
                                        pad.align = reader.attributes().value("align").toString();
                                        def.paddings.append(pad);
                                        reader.skipCurrentElement();
                                    } else {
                                        reader.skipCurrentElement();
                                    }
                                }
                                widget.model.definition = def;
                            }
                            // 处理runtime分支
                            else if (reader.name() == "runtime") {
                                ModelRunTime runtime;
                                while (reader.readNextStartElement()) {
                                    if (reader.name() == "msg") {
                                        Msg msg;
                                        msg.value = "";
                                        runtime.msgs.append(msg);
                                        reader.skipCurrentElement();
                                    } else {
                                        reader.skipCurrentElement();
                                    }
                                }
                                widget.model.modelRunTime = runtime;
                            }
                            else {
                                reader.skipCurrentElement();
                            }
                        }
                    }
                    // 处理events分支
                    else if (reader.name() == "events") {
                        WidgetEvents events;
                        while (reader.readNextStartElement()) {
                            if (reader.name() == "msg") {
                                EventMsg em;
                                em.msgType = reader.attributes().value("type").toString();
                                events.EventMsgs.append(em);
                            }
                            reader.skipCurrentElement();
                        }
                        widget.events = events;
                    }
                    else {
                        reader.skipCurrentElement();
                    }
                }
            }
        }

        if (!reader.hasError()) {
            // 后处理默认值
            if (!rule.name.isEmpty())
            {
                rule.widgetExtension = widget;
                eRules.extensionRules.append(rule);
            }
        }
        xmlFile.close();
    }
}
